package br.uece.laconi.tac;
import java.io.IOException;

import jmetal.util.JMException;
import se.sics.tac.aw.Bid;
import se.sics.tac.aw.TACAgent;
import br.uece.laconi.tac.adapt.AdaptAllocation;
import br.uece.laconi.tac.ga.GA4TAC;

public class Alocador extends GA4TAC {
 
	private BaseDeConhecimento bc;
	private Agent agent;
	private AdaptAllocation agendarAlocacao;
	
	public Alocador(){
		super();		
	}
	public Alocador(Agent agent){
		this();
		setBaseDeConhecimento(agent.base);
		copyFromBC();
		agendarAlocacao = new AdaptAllocation(this);
	}
	
	public void init(long tempo){
		agendarAlocacao.init(tempo);
	}

	public BaseDeConhecimento getBaseDeConhecimento() {
		return bc;
	}

	public void setBaseDeConhecimento(BaseDeConhecimento baseDeConhecimento) {
		this.bc = baseDeConhecimento;
	}
	
	public void solve() throws JMException, SecurityException, IOException {
		copyFromBC();
		execute();
		copyToBC();
	}
	
	public void copyFromBC(){
		setAsk(bc.getAsko());
		setBid(bc.getBido());
		setOwn(bc.getInventario());
		setPrecoEstimadoPr(bc.getPrecoEstimadoPr());
		setPrecoEstimadoRN(bc.getPrecoEstimadoRN());
		setPreferences(bc.getPreferencias());
	}
	
	public void copyToBC(){
		double utilidade = this.getUtilidade();
		bc.setUltimaUtilidadeCalculada(utilidade);
		double maxUtilidade = bc.getMaxUtilidade();
		double ultimaUtilidadeCalc = bc.getUltimaUtilidadeCalculada();
		maxUtilidade += maxUtilidade*0.05d;
		//se utilidade calculada pelo GA for 5% maior que a utilidade anterior
		if(maxUtilidade < ultimaUtilidadeCalc){
			System.out.println("#### MELHOROU UTILIDADE #### - Utilidade anterior " + maxUtilidade + " utilidade atual " + ultimaUtilidadeCalc);
			bc.setMaxUtilidade(utilidade);
			bc.setCompra(getComprar());
			bc.setVende(getVender());
		}
		if(!bc.isPrimeiraAlocacao())
			desalocarLances();
	}
	
	public void desalocarLances(){
		Bid [] comprado = bc.getLancesCompraEnviados();
		Bid [] vendido = bc.getLancesVendaEnviados();
		int [][] comprar = bc.getCompra();
		int [][] vender = bc.getVende();
		for (int i = 0; i < comprado.length; i++) {
			if(comprado[i].getAuction() != 0){
				if((int)comprado[i].getPrice(0) != 0){
					int dia = TACAgent.getAuctionDay(comprado[i].getAuction()) - 1;
					int tipo = TACAgent.getAuctionType(comprado[i].getAuction()) - 1;
					/* se o lance jah foi enviado e o GA retornou que nao quer mais comprar entao sobrescreve lance anterior*/
					if(comprar[dia][tipo] == 0){
						if(!comprado[i].isPreliminary()){
							Bid b = new Bid(comprado[i].getAuction());
							b.addBidPoint(comprado[i].getQuantity(), 0.0f);
							agent.getTACAgent().replaceBid(comprado[i], b);
							System.out.println("REPLACE AFTER ALLOCTION");
							System.out.println(" OLD BUY BID AUCTION " + TACAgent.getAuctionTypeAsString(comprado[i].getAuction()) + " QUANTITY " + comprado[i].getQuantity() + " PRICE " + comprado[i].getPrice(0));
							System.out.println(" NEW BUY BID AUCTION " + TACAgent.getAuctionTypeAsString(b.getAuction()) + " QUANTITY " + b.getQuantity() + " PRICE " + b.getPrice(0));
							comprado[i] = b;
						}
					}
				}
			}
			if(vendido[i].getAuction() != 0){
				if((int)vendido[i].getPrice(0) != 200){
					int dia = TACAgent.getAuctionDay(vendido[i].getAuction()) - 1;
					int tipo = TACAgent.getAuctionType(vendido[i].getAuction()) - 1;
					/* se o lance jah foi enviado e o GA retornou que nao quer mais vender entao sobrescreve lance anterior*/
					if(vender[dia][tipo] == 0){
						if(!vendido[i].isPreliminary()){
							Bid b = new Bid(vendido[i].getAuction());
							b.addBidPoint(-Math.abs(vendido[i].getQuantity()), 200.0f);
							agent.getTACAgent().replaceBid(vendido[i], b);
							System.out.println("REPLACE AFTER ALLOCTION");
							System.out.println(" OLD SELL BID AUCTION " + TACAgent.getAuctionTypeAsString(vendido[i].getAuction()) + " QUANTITY " + (-Math.abs(vendido[i].getQuantity())) + " PRICE " + vendido[i].getPrice(0));
							System.out.println(" NEW SELL BID AUCTION " + TACAgent.getAuctionTypeAsString(b.getAuction()) + " QUANTITY " + (-Math.abs(b.getQuantity())) + " PRICE " + b.getPrice(0));
							vendido[i] = b;
						}
					}
				}
			}
		}
	}
}
 
